package com.open.demo.location

import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest
import com.google.android.libraries.places.api.net.PlacesClient
import com.open.demo.R


/**
 * DEMO 代码:
 * https://github.com/googlecodelabs/while-in-use-location/blob/master/complete/src/main/java/com/example/android/whileinuselocation/ForegroundOnlyLocationService.kt
 *
 * User Location & Permissions：
 * https://www.raywenderlich.com/books/android-apprentice/v4.0/chapters/14-user-location-permissions
 *
 * 需要的权限:
 * ACCESS_FINE_LOCATION则 允许APP通过GPS_PROVIDER获取精确位置信息
 * ACCESS_COARSE_LOCATION权限 允许在APP中通过NETWORK_PROVIDER来获取粗略位置信息
 *
 * @Author: hailong.qiu hailong.qiu@xgimi.com
 * @Maintainer: hailong.qiu hailong.qiu@xgimi.com
 * @Date: 2021/7/8
 * @Copyright: 2021 www.xgimi.com Inc. All rights reserved.
 */
class GmsActivity : AppCompatActivity(), OnMapReadyCallback {

    private var map: GoogleMap? = null
    // The entry point to the Fused Location Provider.
    private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
    // The entry point to the Places API.
    private lateinit var placesClient: PlacesClient
    private var lastKnownLocation: Location? = null

    // A default location (Sydney, Australia) and default zoom to use when location permission is
    // not granted.
    //    private val defaultLocation = LatLng(-33.8523341, 151.2106085)
    // 成都市的经纬度
    private val defaultLocation = LatLng(30.539366, 104.056521)

    companion object {
        const val TAG = "GMS Demo"
        private const val DEFAULT_ZOOM = 15
        private const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 250
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)
        // 初始化定位服务与地图
        initGmsGoogleMapsPlatform()
    }

    private fun initGmsGoogleMapsPlatform() {
        // Construct a PlacesClient
        Places.initialize(this, "AIzaSyCXeMGC2vorGU-G1Pb-0erzz9p7CnG-RfU")
        placesClient = Places.createClient(this)

        // Construct a FusedLocationProviderClient.
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

        // 谷歌地图
        // Build the map.
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment?.getMapAsync(this)
    }

    override fun onMapReady(googleMap: GoogleMap) {
        this.map = googleMap
        Log.d(TAG, "onMapReady googleMap:${googleMap}")
        googleMap.setInfoWindowAdapter(object : GoogleMap.InfoWindowAdapter {
            override fun getInfoWindow(marker: Marker): View? {
                Log.d(TAG, "onMapReady getInfoWindow marker:${marker}")
                return null
            }

            override fun getInfoContents(marker: Marker): View? {
                Log.d(TAG, "onMapReady getInfoContents marker:${marker}")
                // Inflate the layouts for the info window, title and snippet.
                val infoWindow = layoutInflater.inflate(R.layout.custom_info_contents,
                    findViewById<FrameLayout>(R.id.map), false)
                val title = infoWindow.findViewById<TextView>(R.id.title)
                title.text = marker.title
                val snippet = infoWindow.findViewById<TextView>(R.id.snippet)
                snippet.text = marker.snippet
                return infoWindow;
            }
        })
        googleMap.setOnMapClickListener {
        }
        googleMap.setOnMapLongClickListener {
        }

        // 定位权限
        getLocationPermission()

        //
        updateLocationUI()

        // 获取 Android 设备的位置
        getDeviceLocation()

        // 获取设备当前位置的可能地点列表
        showCurrentPlace()
    }

    private var locationPermissionGranted = false

    private fun getLocationPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            locationPermissionGranted = true
        } else {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION)
        }
    }

    /**
     * 获取 Android 设备的位置
     */
    @SuppressLint("MissingPermission")
    private fun getDeviceLocation() {
        if (locationPermissionGranted) {
            val locationResult = fusedLocationProviderClient.lastLocation
            locationResult.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    // getDeviceLocation successful null
                    Log.d(TAG, "getDeviceLocation addOnCompleteListener successful ${task.result}")
                    // Set the map's camera position to the current location of the device.
                    lastKnownLocation = task.result
                    if (null != lastKnownLocation) {
                        Log.d(
                            TAG, "getDeviceLocation addOnCompleteListener successful " +
                                    "latitude:${lastKnownLocation?.latitude} longitude:${lastKnownLocation?.longitude}"
                        )
                    } else {
                        map?.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLocation, DEFAULT_ZOOM.toFloat()))
                        map?.uiSettings?.isMyLocationButtonEnabled = false
                    }
                } else {
                    Log.d(TAG, "getDeviceLocation addOnCompleteListener Exception:${task.exception}")
                    // 当前 location 为 null. 使用默认Location.
                    map?.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLocation, DEFAULT_ZOOM.toFloat()))
                    map?.uiSettings?.isMyLocationButtonEnabled = false
                }
            }
            locationResult.addOnSuccessListener { location: Location? ->
                Log.d(TAG, "getDeviceLocation addOnSuccessListener location:${location}")
            }
        }
    }

    /**
     * 获取设备当前位置的可能地点列表
     */
    private fun showCurrentPlace() {
        if (map == null) {
            return
        }
        if (locationPermissionGranted) {
            // Use fields to define the data types to return.
            val placeFields = listOf(Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG)
            // Use the builder to create a FindCurrentPlaceRequest.
            val request = FindCurrentPlaceRequest.newInstance(placeFields)

            // Get the likely places - that is, the businesses and other points of interest that
            // are the best match for the device's current location.
            val placeResult = placesClient.findCurrentPlace(request)
            placeResult.addOnCompleteListener { task ->
                if (task.isSuccessful && task.result != null) {
                    Log.d(TAG, "showCurrentPlace addOnCompleteListener ${task.isSuccessful} ${task.result}")
                } else {
                    // error: com.google.android.gms.common.api.ApiException: 8: Location unavailable.
                    // https://github.com/googlesamples/google-services/issues/445
                    Log.d(TAG, "showCurrentPlace addOnCompleteListener Exception:${task.exception}")
                }
            }
        } else {
            Log.d(TAG, "showCurrentPlace The user did not grant location permission.")
            // Add a default marker, because the user hasn't selected a place.
            map?.addMarker(
                MarkerOptions()
                .title("测试标题")
                .position(defaultLocation)
                .snippet("辣鸡定位服务"))

            // Prompt the user for permission.
            getLocationPermission()
        }
    }

    @SuppressLint("MissingSuperCall")
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        locationPermissionGranted = false
        when (requestCode) {
            PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    locationPermissionGranted = true
                }
            }
        }
        updateLocationUI()
    }

    private fun updateLocationUI() {
        if (map == null) {
            return
        }
        try {
            if (locationPermissionGranted) {
                map?.isMyLocationEnabled = true
                map?.uiSettings?.isMyLocationButtonEnabled = true
            } else {
                map?.isMyLocationEnabled = false
                map?.uiSettings?.isMyLocationButtonEnabled = false
                lastKnownLocation = null
                getLocationPermission()
            }
        } catch (e: SecurityException) {
            Log.e(TAG, "Exception:${e.message}")
        }
    }

}